/**
 * 折线图、柱状图、面积图、点状图、堆叠折现图、堆叠面积图、堆叠柱状图
 * BigEventC (reactCharts)
 * @author zxy
 * @date  2020-11-27
 */
import React from 'react';
import PropTypes from 'prop-types';
import ReactEcharts from 'echarts-for-react';
import { Spin } from 'antd';
import { NoDataC } from '@/src/components/other';
import Color from '../../../css/colors';
import _ from 'lodash';
import moment from 'moment';

class BigEventC extends React.Component {
  // 入参默认值设置
  static defaultProps = {
    series: undefined,
    height: '100%', // 图形高度默认为父节点的100%
    width: '100%', // 图形宽度默认为父节点的100%
    dataZoom: false, // 默认无横向滚动轴
    colors: Color.bigEventEchart, // 默认系统色
    title: '', // 标题默认为空
    showBorder: false, // 默认不展示外边框
    toolTipFormat: undefined, // 默认按自定义的提示信息样式展示
    gridLeft: 60, // 默认左轴距离左侧距离为60
    gridRight: 60, // 默认右轴距离右侧距离为60
    isShowLegent: true, // 默认展示图例
    beginDate: undefined, // 默认无开始日期
    endDate: undefined, // 默认无结束日期
  };

  // 返回option
  getOption = (xAxis, min, max, series, legend) => {
    const { colors, title, showBorder, toolTipFormat, gridLeft, gridRight, beginDate, endDate, dataZoom, colorType } = this.props;
    let colorss;
    switch (colorType) {
      case 'darkBlue':
        colorss = Color.darkBlueBigEventEchart;
        break;
      case 'red':
        colorss = Color.redBigEventEchart;
        break;
      default:
        colorss = colors;
    }
    return {
      // 调色盘颜色列表
      color: colorss,
      backgroundColor: colorType == 'red' ? Color.echartItems.bgColorR : colorType == 'darkBlue' ? Color.echartItems.bgColorD : Color.echartItems.bgColor, //echarts整个画布的背景色
      // 主标题和副标题
      title: {
        show: title ? true : false,
        left: '20',
        top: showBorder ? 30 : 20,
        text: title,
        textStyle: {
          color: Color.echartItems.title,
          fontSize: 14,
          fontWeight: 'normal',
          lineHeight: 20,
        },
      },
      // 鼠标移动上去提示信息
      tooltip: {
        trigger: 'axis',
        show: true,
        axisPointer: {
          type: 'none', // tooltip展示十字型
          crossStyle: {
            color: Color.echartItems.tooltipCross,
          },
          label: {
            show: false,
            backgroundColor: Color.echartItems.tooltipBg,
            color: Color.echartItems.tooltipLabel,
            padding: [7, 7, 5, 7],
          },
        },
        formatter: toolTipFormat
          ? toolTipFormat
          : (params) => {
            let haveFHPS = false; // 是否包含分红配送
            let FHPSposi = -1; // 分红配送所在数组的位置
            params &&
            params.forEach((element, index) => {
              if (element.seriesName == '分红配送' && element.data != '') {
                haveFHPS = true;
                FHPSposi = index;
              }
            });
            // 只展示分红配送的tooltip
            if (haveFHPS == false) {
              return;
            }

            let str = `<div style="color:${Color.echartItems.tooltipLabel}">`;
            str += `<div style="margin-top:8px">${params[FHPSposi].data.date}</div>`;
            str += `<div style="margin-top:8px">${params[FHPSposi].data.event}</div>`;
            str += '</div>';
            return str;
          },
        padding: [12, 12, 12, 12],
        confine: true,
        backgroundColor: Color.echartItems.tooltipBgColor,
        extraCssText: `box-shadow: 0px 2px 12px 0px ${Color.echartItems.tooltipBgShadow};border-radius: 4px;opacity: 0.65;font-size: 12px;font-family: PingFangSC-Regular, PingFang SC;font-weight: 400;`,
      },
      // 图例
      legend: {
        show: true,
        data: legend,
        bottom: 15,
        right: 20,
        textStyle: {
          color: Color.echartItems.legend,
          fontSize: 12,
        },
        itemWidth: 20,
        itemHeight: 14,
        borderRadius: [0, 0, 0, 0],
      },
      // 直角坐标系内绘图网格
      grid: {
        left: gridLeft,
        right: gridRight,
        top: 50,
        bottom: dataZoom ? 112 : 77,
      },
      // 横轴
      xAxis: {
        type: 'category',
        data: xAxis,
        axisLine: {
          lineStyle: {
            color: Color.echartItems.xAxisLine,
          },
        },
        axisTick: {
          show: false,
        },
        axisLabel: {
          color: Color.echartItems.xAxisLabel,
          margin: 6, // 与横轴的距离
          fontSize: 12,
          showMinLabel: true,
          showMaxLabel: true,
          formatter: (value) => {
            // 只展示开始日期和结束日期
            if (value === beginDate) {
              return `${value}(成立日)`;
            }
            if (value === endDate) {
              return `${value}(当前日)`;
            }
          },
        },
      },
      // 纵轴
      yAxis: {
        type: 'value',
        axisLine: {
          show: false,
        },
        axisTick: {
          // Y轴间隔小线段样式
          show: false,
        },
        axisLabel: {
          // Y轴文本样式
          show: false,
        },
        splitNumber: 6, // 坐标轴的分割段数，需要注意的是这个分割段数只是个预估值，最后实际显示的段数会在这个基础上根据分割后坐标轴刻度显示的易读程度作调整
        splitLine: {
          // Y轴分割线样式
          show: false,
          lineStyle: {
            type: 'dashed',
            color: Color.echartItems.splitLine,
          },
        },
        min: min,
        max: max,
      },
      // 横向滚动条
      dataZoom: dataZoom
        ? {
          ...dataZoom,
          bottom: legend.length > 1 ? 45 : 20,
          height: 40,
          left: 20,
          right: 20,
          handleColor: Color.echartItems.dataZoomHandBg, //滑动图标的颜色
          borderColor: Color.echartItems.dataZoomBorderBg, // 边框颜色
          backgroundColor: Color.echartItems.dataZoomBg, //滚动条未选中区域的背景颜色
          dataBackground: {
            lineStyle: {
              color: Color.echartItems.dataZoomShadowBg,
            },
            areaStyle: {
              color: Color.echartItems.dataZoomShadowBg, //滚动条数据阴影区域的背景颜色
              shadowColor: Color.echartItems.dataZoomShadowBg, //滚动条数据阴影区域的背景颜色
            },
          },
          fillerColor: Color.echartItems.dataZoomChoosedBg, //滚动条选中区域的背景颜色
        }
        : [],
      // 数据
      series: series,
    };
  };

  // 找出给定日期范围内所有日期，以数组形式返回；
  getAllDate = (beginDate, endDate) => {
    let bt = moment(beginDate, 'YYYY-MM-DD');
    let dates = [];
    while (bt.format('YYYY-MM-DD') <= endDate) {
      dates.push(bt.format('YYYY-MM-DD'));
      bt = bt.add(1, 'day');
    }
    return dates;
  };

  initEchartsEvent = (e) => {
    if (!e) return;

    this.echartsIsInit = true; // 标记echarts已初始化完毕
    this.echarts_react = e;
    this.echarts_instance = e.getEchartsInstance(); // echarts实例
  };
  render() {
    const { series, beginDate, endDate, showBorder, width, height } = this.props;

    let initStatus = !!series && !!beginDate && !!endDate; // 标记是否达到初始化状态(true:可以初始化图表，false：还未获取到数据)

    let xAxis = []; // 横轴
    let min = 0; // 纵轴最大值
    let max = 0; // 纵轴最小值
    let seriesN = []; // 新构建的series
    let legend = []; // 图例
    if (initStatus) {
      // 获取横轴时间
      xAxis = this.getAllDate(beginDate, endDate);
      let hasPositive = false; // 无正数（根据该值判断纵轴最大值和最小值）
      let hasNegative = false; // 无负数（根据该值判断纵轴最大值和最小值）

      // 遍series,构建新的series对象
      series.forEach((element) => {
        // 构建图例
        legend.push(element.name);

        // 构建空data
        let dateInSeries = [];
        for (let i = 0; i < xAxis.length; i++) {
          dateInSeries.push('');
        }

        let markPointDT = []; // 存储markPoint数据
        let fhPrePosi = ''; // 记录上一个分红配送的位置（一个在上，一个在下，交叉展示）
        let fhLableShow = true; // 分红配送时，当大于20个点，不展示lable

        // 遍历series中的data，构建series中每一项的data
        element.data.forEach((item) => {
          let position = ''; // lable的位置（正数和0在top，负数在bottom）
          // 只要有一个正值，max设为12，一个为负值，min为-10
          if (item.value < 0) {
            hasNegative = true;
            position = 'bottom';
          }
          if (item.value > 0) {
            hasPositive = true;
            position = 'top';
          }
          // 分红配送
          if (item.value == 0) {
            if (element.data.length > 20) fhLableShow = false; // 判断分红配送的点是否多于20个
            position = fhPrePosi == 'top' ? 'bottom' : 'top';
            fhPrePosi = position;
          }
          // 将匹配日期的项填上数据
          dateInSeries[xAxis.indexOf(item.date)] = { ...item, label: { position: position, show: fhLableShow } };
          // 构建markPoint数据
          markPointDT.push({ coord: [item.date, item.value] });
        });
        seriesN.push({
          name: element.name,
          data: dateInSeries,
          type: 'bar',
          barWidth: 2,
          label: {
            show: true,
            distance: 10,
            formatter: (params) => {
              return `${params.name}
${dateInSeries[params.dataIndex].event}`;
            },
          },
          markPoint: {
            symbol: 'circle',
            symbolSize: 10,
            label: {
              show: false,
            },
            //  symbolOffset: ['-50%', 0],
            data: markPointDT,
          },
        });
      });

      // 处理纵轴数据的最大值和最小值
      max = hasPositive ? 12 : 0;
      min = hasNegative ? -12 : 0;
    }

    return (
      <div style={{ border: showBorder && `1px solid ${Color.echartItems.border}`, width: width }}>
        <Spin spinning={!initStatus} tip='加载中...'>
          {initStatus ? (
            series.length > 0 && xAxis.length > 0 ? (
              <ReactEcharts
                option={this.getOption(xAxis, min, max, seriesN, legend)}
                style={{ height: height, width: width }}
                // 是否不跟之前设置的 option 进行合并，默认为 false，即合并。
                notMerge={true}
                ref={this.initEchartsEvent}
              />
            ) : (
              <NoDataC />
            )
          ) : (
            // <Empty description='暂无数据' style={{height:this.state.chartHeight,display:'flex',justifyContent:'center',alignItems:'center',flexDirection:'column'}}></Empty>
            <div style={{ height: height, width: width }}></div>
          )}
        </Spin>
      </div>
    );
  }
}

/*
备注：
  当beginDate、endDate和series值为null或undefined时，显示loading状态
  当beginDate、endDate和series值为空数组[]时，显示“暂无数据”
  当beginDate、endDate和series值为有值的数组时，正常实现图形
*/
BigEventC.propsTypes = {
  beginDate: PropTypes.string, // 横轴起始时间
  endDate: PropTypes.string, // 横轴结束时间
  series: PropTypes.array, // 纵轴数据（[{name:xxxx,data:[{value:xx,date:YYYY-MM-DD,event:xxxx},...]},...]）
  height: PropTypes.oneOfType([
    // 图表高度（百分比、数值、auto(自动根据图例数量计算高度)）
    PropTypes.string,
    PropTypes.number,
  ]),
  width: PropTypes.oneOfType([
    // 图表宽度（百分比或数值）
    PropTypes.string,
    PropTypes.number,
  ]),
  dataZoom: PropTypes.oneOfType([
    // 是否有横向滚动轴（{startValue: 0,endValue: 5}）
    PropTypes.bool,
    PropTypes.object,
  ]),
  colors: PropTypes.array, // 图表颜色
  title: PropTypes.string, // 标题
  toolTipFormat: PropTypes.func, // 提示框内容显示格式处理
  showBorder: PropTypes.bool, // 是否显示图形外层边框
  gridLeft: PropTypes.number, // 左轴距离左侧的距离
  gridRight: PropTypes.number, // 右轴距离右侧的距离
  isShowLegent: PropTypes.bool, // 是否展示图例
};

export default BigEventC;
